package com.zmn.oms.zmn.business.impl.compensate;

import com.alibaba.fastjson.JSON;
import com.google.common.collect.Lists;
import com.zmn.common.constant.GlobalConsts;
import com.zmn.common.utils.collection.CollectionUtil;
import com.zmn.common.utils.date.DateUtil;
import com.zmn.common.utils.reflect.BeanMapper;
import com.zmn.oms.business.interfaces.base.BaseCodeService;
import com.zmn.oms.business.interfaces.remark.OrderRemarkBService;
import com.zmn.oms.common.annotation.OrderWorkChangeSync;
import com.zmn.oms.common.annotation.ZsNormalOrderWorkLog;
import com.zmn.oms.common.constant.OrderConsts;
import com.zmn.oms.common.constant.OrderLogConsts;
import com.zmn.oms.common.constant.OrderStatusConsts;
import com.zmn.oms.common.dto.OmsOperator;
import com.zmn.oms.common.exception.OmsBaseException;
import com.zmn.oms.common.vo.KVDict;
import com.zmn.oms.model.dto.order.zmn.ZsNormalCompensateWorkDTO;
import com.zmn.oms.model.dto.remark.OrderRemarkDTO;
import com.zmn.oms.model.dto.remark.OrderRemarkDetailDTO;
import com.zmn.oms.model.dto.work.compensate.CompensateDTO;
import com.zmn.oms.model.dto.work.compensate.CompensateReviewDTO;
import com.zmn.oms.model.dto.work.compensate.RemitVoucherDTO;
import com.zmn.oms.model.entity.compensate.OmsOrderCompensate;
import com.zmn.oms.model.entity.pay.OrderPay;
import com.zmn.oms.model.entity.review.OmsOrderReview;
import com.zmn.oms.model.entity.work.OrderWork;
import com.zmn.oms.model.vo.remark.OrderRemarkDetailVO;
import com.zmn.oms.model.vo.remark.OrderRemarkVO;
import com.zmn.oms.model.vo.work.OperatePermissionVO;
import com.zmn.oms.model.vo.work.compensate.CompensateVO;
import com.zmn.oms.services.interfaces.compensate.OrderWorkCompensateService;
import com.zmn.oms.services.interfaces.pay.OrderPayService;
import com.zmn.oms.services.interfaces.review.OmsOrderReviewService;
import com.zmn.oms.services.interfaces.work.OrderWorkService;
import com.zmn.oms.zmn.business.interfaces.compensate.CompensateBService;
import com.zmn.oms.zmn.business.interfaces.work.ZsOrderWorkOperatePermissionBService;
import com.zmn.oms.zmn.normal.business.interfaces.review.OmsOrderReviewBService;
import com.zmn.oms.zmn.normal.business.interfaces.work.ZsNormalWorkBService;
import com.zmn.pay.common.constant.PayConsts;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @ClassName CompensateBService
 * @description:
 * @author: wangyanci
 * @create: 2021-08-18 18:43
 * @Version 1.0
 **/
@Slf4j
@Service
public class CompensateBServiceImpl implements CompensateBService {

    // 赔偿缘由一级id
    private static final int BASE_CODE_MAP_ONE_TYPE_OMS_COMPENSATE_REASON = 1098;

    @Autowired
    private OrderWorkService orderWorkService;
    @Autowired
    private OmsOrderReviewService orderReviewService;
    @Autowired
    ZsNormalWorkBService zsNormalWorkBService;
    @Autowired
    private OmsOrderReviewBService orderReviewBService;
    @Autowired
    OrderRemarkBService orderRemarkBService;
    @Autowired
    private OrderWorkCompensateService orderWorkCompensateService;
    @Autowired
    private OrderPayService orderPayService;
    @Autowired
    private BaseCodeService baseCodeService;
    @Autowired
    private ZsOrderWorkOperatePermissionBService orderWorkOperatePermissionBService;

    @ZsNormalOrderWorkLog(type = OrderLogConsts.ORDER_LOG_TYPE_REMIT_VOUCHER, beforeProceed = false)
    @Transactional(rollbackFor = Exception.class)
    @Override
    public OrderWork saveRemitVoucher(RemitVoucherDTO remitVoucherDTO) {
        OrderPay refundPay = orderPayService.getOrderWorkRefundPay(remitVoucherDTO.getOrderId(), remitVoucherDTO.getWorkId());
        OrderWork updateOrderWork = new OrderWork();
        updateOrderWork.setOrderId(remitVoucherDTO.getOrderId());
        updateOrderWork.setWorkId(remitVoucherDTO.getWorkId());
        if (Objects.isNull(refundPay)) {
            // 作用：log
            remitVoucherDTO.setStatus(OrderStatusConsts.WORK_STATUS_COMPLETE);
            // 添加orderPay
            OmsOrderCompensate orderCompensate = orderWorkCompensateService.findOmsOrderCompensateByOrderIdAndWorkId(remitVoucherDTO.getOrderId(), remitVoucherDTO.getWorkId());
            refundPay = new OrderPay();
            refundPay.setOrderId(remitVoucherDTO.getOrderId());
            refundPay.setWorkId(remitVoucherDTO.getWorkId());
            refundPay.setAmountType(0);
            refundPay.setTradeType(PayConsts.PAY_TRADE_TYPE_REFUND);
            refundPay.setRefundType(OrderConsts.ORDER_REFUND_TYPE_OFFLINE);
            refundPay.setPayStatus(PayConsts.REFUND_STATUS_DONE);
            refundPay.setPayChannelId(PayConsts.PAY_CHANNEL_PLATFORM_OFFLINE);
            refundPay.setPayTargetChannelId(orderCompensate.getCompensateType());
            refundPay.setPayType(PayConsts.PAY_TYPE_MANUAL);
            refundPay.setPayTime(DateUtil.getNow());
            refundPay.setAmount(orderCompensate.getCompensateAmount());
            refundPay.setRefundImageData(JSON.toJSONString(remitVoucherDTO.getRefundVoucherData()));
            refundPay.setPayerThirdAccount(remitVoucherDTO.getPayerThirdAccount());
            refundPay.setPayerThirdAccountBank(remitVoucherDTO.getPayerThirdAccountBank());
            refundPay.setCreater(remitVoucherDTO.getOperator());
            refundPay.setUpdater(remitVoucherDTO.getOperator());
            refundPay.setCreateTime(DateUtil.getNow());
            refundPay.setUpdateTime(DateUtil.getNow());
            orderPayService.insertOrderPay(refundPay);

            // 修改工单退款状态
            updateOrderWork.setPayStatus(PayConsts.REFUND_STATUS_DONE);
            updateOrderWork.setUpdateTime(DateUtil.getNow());
            updateOrderWork.setUpdater(remitVoucherDTO.getOperator());
            updateOrderWork.setStatus(OrderStatusConsts.WORK_STATUS_COMPLETE);
            updateOrderWork.setCompleteTime(DateUtil.getNow());
            orderWorkService.updateOrderWorkByKey(updateOrderWork);
        }else {
            OrderPay updateOrderPay = new OrderPay();
            updateOrderPay.setOrderPayId(refundPay.getOrderPayId());
            updateOrderPay.setOrderId(remitVoucherDTO.getOrderId());
            updateOrderPay.setWorkId(remitVoucherDTO.getWorkId());
            updateOrderPay.setUpdater(remitVoucherDTO.getOperator());
            updateOrderPay.setUpdateTime(DateUtil.getNow());
            updateOrderPay.setRefundImageData(JSON.toJSONString(remitVoucherDTO.getRefundVoucherData()));
            updateOrderPay.setPayerThirdAccount(remitVoucherDTO.getPayerThirdAccount());
            updateOrderPay.setPayerThirdAccountBank(remitVoucherDTO.getPayerThirdAccountBank());
            orderPayService.updateByPrimaryKeySelective(updateOrderPay);
        }
        return updateOrderWork;
    }


    @ZsNormalOrderWorkLog(type = OrderLogConsts.ORDER_LOG_TYPE_COMPENSATE_REVIEW, beforeProceed = false)
    @Transactional(rollbackFor = Exception.class)
    @Override
    public OrderWork reviewCompensate(CompensateReviewDTO compensateReviewDTO) throws OmsBaseException {
        // 工单状态
//        compensateReviewDTO.setStatus(Objects.equals(compensateReviewDTO.getReviewStatus(), GlobalConsts.YES) ? OrderStatusConsts.WORK_STATUS_COMPLETE : null);
        compensateReviewDTO.setResultStatus(Objects.equals(compensateReviewDTO.getReviewStatus(), GlobalConsts.NO) ? OrderStatusConsts.WORK_RESULT_DISCARD : null);

        // 审批完成
        OmsOrderReview compensateReview = orderReviewService.getOmsOrderReviewByOrderIdAndWorkIdAndType(compensateReviewDTO.getOrderId(), compensateReviewDTO.getWorkId(), OrderConsts.OMS_ORDER_REVIEW_COMPENSATE);
        orderReviewBService.reviewComplete(compensateReviewDTO.getReviewStatus(), compensateReview, compensateReviewDTO);

        // 工单状态修改
        OrderWork updateOrderWork = new OrderWork();
        updateOrderWork.setOrderId(compensateReviewDTO.getOrderId());
        updateOrderWork.setWorkId(compensateReviewDTO.getWorkId());
        Date now = DateUtil.getNow();
        if (Objects.equals(compensateReviewDTO.getReviewStatus(), GlobalConsts.NO)) {
            updateOrderWork.setResultTime(DateUtil.getNow());
            updateOrderWork.setResulterId(compensateReviewDTO.getOperatorId());
            updateOrderWork.setResulterType(GlobalConsts.OPERATE_USER_TYPE_STAFF);
            updateOrderWork.setResultStatus(OrderStatusConsts.WORK_RESULT_DISCARD);
            updateOrderWork.setCancelTime(now);
            updateOrderWork.setCancelerId(compensateReviewDTO.getOperatorId());
        } else if (Objects.equals(compensateReviewDTO.getReviewStatus(), GlobalConsts.YES)) {
            updateOrderWork.setUpdater(compensateReviewDTO.getOperator());
//            updateOrderWork.setStatus(OrderStatusConsts.WORK_STATUS_COMPLETE);
//            updateOrderWork.setCompleteTime(now);
        }else {
            throw new OmsBaseException("审核结果不合法！");
        }
        orderWorkService.updateOrderWorkByKey(updateOrderWork);

        // 损坏物品、附件图片保存
        if (Objects.equals(compensateReviewDTO.getReviewStatus(), GlobalConsts.YES)) {
            CompensateDTO compensateReviewData = JSON.parseObject(compensateReview.getReviewData(), CompensateDTO.class);
            OmsOrderCompensate orderCompensate = BeanMapper.map(compensateReviewData, OmsOrderCompensate.class);
            orderCompensate.setOrderId(compensateReviewDTO.getOrderId());
            orderCompensate.setWorkId(compensateReviewDTO.getWorkId());
            orderCompensate.setCompensateType(compensateReviewData.getPayTargetChannelId());
            orderCompensate.setImageUrls(String.join(",", compensateReviewData.getImageUrls()));
            orderCompensate.setCreater(compensateReviewDTO.getOperator());
            orderWorkCompensateService.insertOmsOrderCompensate(orderCompensate);
        }
        return updateOrderWork;
    }

    @ZsNormalOrderWorkLog(type = OrderLogConsts.ORDER_LOG_TYPE_COMPENSATE_UPDATE, beforeProceed = false)
    @Transactional(rollbackFor = Exception.class)
    @Override
    public OrderWork updateCompensate(CompensateDTO compensateDTO) throws OmsBaseException {
        OrderWork compensateOrderWork = orderWorkService.findOrderWorkByKey(compensateDTO.getOrderId(), compensateDTO.getWorkId());
        orderReviewBService.initiateCompensateReview(compensateOrderWork, compensateDTO);


        // 修改赔偿单金额
        OrderWork updateOrderWork = new OrderWork();
        updateOrderWork.setOrderId(compensateOrderWork.getOrderId());
        updateOrderWork.setWorkId(compensateOrderWork.getWorkId());
        updateOrderWork.setTotalAmount(Optional.ofNullable(compensateDTO.getCompensateAmount()).orElse(0) * -1);
        updateOrderWork.setOriginalAmount(Optional.ofNullable(compensateDTO.getCompensateAmount()).orElse(0) * -1);
        updateOrderWork.setUpdater(compensateDTO.getOperator());
        updateOrderWork.setUpdateTime(DateUtil.getNow());
        orderWorkService.updateOrderWorkByKey(updateOrderWork);

        // 保存退款缘由
        OrderRemarkDTO orderRemarkDTO = new OrderRemarkDTO();
        orderRemarkDTO.setOrderId(compensateDTO.getOrderId());
        orderRemarkDTO.setWorkId(compensateDTO.getWorkId());
        orderRemarkDTO.setOperatorId(compensateDTO.getOperatorId());
        orderRemarkDTO.setOperatorType(compensateDTO.getOperatorType());
        orderRemarkDTO.setContent(compensateDTO.getContent());
        if (CollectionUtil.isNotNullOrEmpty(compensateDTO.getReasonList())) {
            List<OrderRemarkDetailDTO> orderRemarkDetailList = Lists.newArrayListWithExpectedSize(compensateDTO.getReasonList().size());
            for (KVDict kvDict : compensateDTO.getReasonList()) {
                orderRemarkDetailList.add(new OrderRemarkDetailDTO(Integer.valueOf(kvDict.getValue().toString()), kvDict.getText(), null, 0));
            }
            orderRemarkDTO.setDetailDTOList(orderRemarkDetailList);
        }
        orderRemarkBService.insertOrderRemark(orderRemarkDTO, OrderConsts.ORDER_REMARK_TYPE_REFUND);

        return compensateOrderWork;
    }

    @OrderWorkChangeSync
    @Transactional(rollbackFor = Exception.class)
    @Override
    public OrderWork commitCompensate(CompensateDTO compensateDTO) throws OmsBaseException {
        OrderWork originalOrderWork = orderWorkService.findOrderWorkByKey(compensateDTO.getOrderId(), compensateDTO.getWorkId());

        ZsNormalCompensateWorkDTO compensateWorkDTO = BeanMapper.map(compensateDTO, ZsNormalCompensateWorkDTO.class);
        compensateWorkDTO.setBizMode(originalOrderWork.getBizMode());
        compensateWorkDTO.setStatus(OrderStatusConsts.WORK_STATUS_INPUT);
        compensateWorkDTO.setResultStatus(OrderStatusConsts.WORK_RESULT_DOING);
        // 新增赔偿单
        OrderWork compensateOrderWork = zsNormalWorkBService.insertCompensateOrderWork(compensateWorkDTO);
        // 添加审批
        orderReviewBService.initiateCompensateReview(compensateOrderWork, compensateDTO);
        return compensateOrderWork;
    }

    @OrderWorkChangeSync
    @Transactional(rollbackFor = Exception.class)
    @Override
    public void cancelCompensateOrder(OrderWork compensateOrderWork, OmsOperator omsOperator) throws OmsBaseException {
        OperatePermissionVO operatePermission = orderWorkOperatePermissionBService
                .getOperatePermission(compensateOrderWork.getOrderId(), compensateOrderWork.getWorkId(), OrderConsts.ORDER_OP_TYPE_CANCEL);
        if (!operatePermission.getCanOperate()) {
            throw new OmsBaseException(operatePermission.getMsg());
        }

        // 更新审核表
        OmsOrderReview compensateOrderReview = orderReviewService.getOmsOrderReviewByOrderIdAndWorkIdAndType(compensateOrderWork.getOrderId(),
                compensateOrderWork.getWorkId(), OrderConsts.OMS_ORDER_REVIEW_COMPENSATE);
        if (Objects.nonNull(compensateOrderReview)) {
            compensateOrderReview.setReviewStatus(OrderConsts.OMS_ORDER_REVIEW_STATUS_CHECK);
            orderReviewBService.stopReview(compensateOrderReview, omsOperator);
        }

        // 更新工单表
        Date now = DateUtil.getNow();
        OrderWork updateOrderWork = new OrderWork();
        updateOrderWork.setOrderId(compensateOrderWork.getOrderId());
        updateOrderWork.setWorkId(compensateOrderWork.getWorkId());
        updateOrderWork.setCancelTime(now);
        updateOrderWork.setCancelerId(omsOperator.getOperatorId());
        updateOrderWork.setCancelerType(omsOperator.getOperatorType());
        updateOrderWork.setResultTime(DateUtil.getNow());
        updateOrderWork.setResulterId(omsOperator.getOperatorId());
        updateOrderWork.setResulterType(omsOperator.getOperatorType());
        updateOrderWork.setResultStatus(OrderStatusConsts.WORK_RESULT_FAIL);
        updateOrderWork.setPayStatus(PayConsts.PAY_STATUS_NONE);
        orderWorkService.updateCancel(updateOrderWork);
    }

    @Override
    public CompensateVO getCompensateVO(Long orderId, Long workId) {
        OrderWork orderWork = orderWorkService.findOrderWorkByKey(orderId, workId);
        CompensateVO compensateVO = new CompensateVO();
        compensateVO.setStatus(orderWork.getStatus());
        compensateVO.setResultStatus(orderWork.getResultStatus());
        // 赔偿原因
        List<KVDict<Integer>> compensateReason = baseCodeService.getBaseCodeMap(GlobalConsts.PLAT_MARK_ZMN, BASE_CODE_MAP_ONE_TYPE_OMS_COMPENSATE_REASON);
        compensateVO.setCompensateReason(compensateReason);
        if (!Objects.equals(orderWork.getType(), OrderConsts.ORDER_TYPE_COMPENSATE)) {
            return compensateVO;
        }
        // 退款缘由
        OrderRemarkVO orderRemarkVO = orderRemarkBService.findOrderRemarkVO(orderId, workId, OrderConsts.ORDER_REMARK_TYPE_COMPENSATE);
        if (Objects.nonNull(orderRemarkVO) && CollectionUtil.isNotNullOrEmpty(orderRemarkVO.getDetailVOList())) {
            Set<Integer> selectedMapIds = orderRemarkVO.getDetailVOList()
                    .stream()
                    .map(OrderRemarkDetailVO::getMapId)
                    .collect(Collectors.toSet());
            for (KVDict<Integer> reason : compensateReason) {
                if (selectedMapIds.contains(reason.getValue())) {
                    reason.setSelected(true);
                }
            }
        }

        OmsOrderReview compensateOrderReview = orderReviewService.getOmsOrderReviewByOrderIdAndWorkIdAndType(orderId, workId, OrderConsts.OMS_ORDER_REVIEW_COMPENSATE);
        CompensateDTO compensateDTO = JSON.parseObject(compensateOrderReview.getReviewData(), CompensateDTO.class);
        compensateVO = BeanMapper.map(compensateDTO, CompensateVO.class);
        compensateVO.setCompensateReason(compensateReason);
        compensateVO.setStatus(orderWork.getStatus());
        compensateVO.setResultStatus(orderWork.getResultStatus());
        return compensateVO;
    }
}
